/*
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    2010 year
 *    Author: Michael Khromov aka MikeDM (Mike D'Morto)
 *    E-Mail: mikedmorto@gmail.com
 */
#include "dloginstdmng.h"
#include "ui_dloginstdmng.h"
#include <QDebug>

DLoginStdMng::DLoginStdMng( bool mode, const QString & curruser,QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DLoginStdMng)
{
    ui->setupUi(this);
    // добавляем кнопку минимизации окна.
    this->setWindowFlags(Qt::WindowMinMaxButtonsHint);

    this->mode=mode;
    this->curruser=curruser;
    this->ui->lw_users->installEventFilter(this);

}

bool DLoginStdMng::dstart(){
    // начинаем работать
    // сначала выясняем в каком режиме нас запустили
    if(this->mode){
        // режим админа
        // необходимо получить список юзероф.
        // предварительно рисуем экран заглушку
        this->Step=DLoginStdMng::GetAllA;
        this->ui->btn_wait->hide();
        this->ui->lbl_wait->setText(tr("Getting all users"));
        this->setWindowTitle(APP_NAME+tr(" - Login manager administrator mode"));
        this->ui->sw->setCurrentIndex(1);
        emit this->sigGetAllUsers();
        this->exec();

    }else{
        // режим пользователя
        // подготавливаем диалог
        this->ui->le_curpass->clear();
        this->ui->le_newpass1->clear();
        this->ui->le_newpass2->clear();
        this->ui->lbl_user->setText(tr("Current user: ")+this->curruser);
        this->ui->sw->setCurrentIndex(0);
        this->setWindowTitle(APP_NAME+tr(" - Login manager user mode"));
        this->Step=DLoginStdMng::ShowU;
        this->exec();
    }
}


void DLoginStdMng::slotAcceptCP(){
    // нажали на кнопочку изменения пароля
    // проверяем на каком этапе нажали кнопочку
    switch(this->Step){
    case DLoginStdMng::ShowU:
        // текущий этап это отображение смены пароля в пользовательском режиме
        // проверяем совпадают ли новые пароли
        if(this->ui->le_newpass1->text() == this->ui->le_newpass2->text()){
            // совпали. делаем запрос на проверку текущего пароля
            // предварительно на вкладке информации запираем пользователя
            // с надписью пааадаааждите.
            this->Step=DLoginStdMng::QueryChangePassU;
            this->ui->lbl_wait->setText(tr("Wait until the end of the query."));
            this->ui->btn_wait->hide();
            this->ui->sw->setCurrentIndex(1);
            emit this->sigChangeUP(this->ui->le_curpass->text());
        }else{
            // несовпали, ругаемся в закладку отображения информации
            this->Step=DLoginStdMng::ValidPassErrU;
            this->ui->lbl_wait->setText(tr("Error: new passwords do not match."));
            this->ui->btn_wait->setText(tr("Back"));
            this->ui->btn_wait->setFocus();
            this->ui->sw->setCurrentIndex(1);
        }
        break;
    case DLoginStdMng::ShowUA:
        // текущий этап это отображение смены пароля в админском режиме
        // проверяем совпадают ли новые пароли
        if(this->ui->le_newpass1->text() == this->ui->le_newpass2->text()){
            // совпали. делаем запрос на проверку текущего пароля
            // предварительно на вкладке информации запираем пользователя
            // с надписью пааадаааждите.
            this->Step=DLoginStdMng::QueryChangePassUA;
            this->ui->lbl_wait->setText(tr("Wait until the end of the query."));
            this->ui->btn_wait->hide();
            this->ui->sw->setCurrentIndex(1);
            //emit this->sigChangeUP(this->ui->le_curpass->text());
            emit this->sigChangeUPA(this->ui->le_newpass1->text(),this->ui->lw_users->currentItem()->text());
        }else{
            // несовпали, ругаемся в закладку отображения информации
            this->Step=DLoginStdMng::ValidCurrPassErrUA;
            this->ui->lbl_wait->setText(tr("Error: new passwords do not match."));
            this->ui->btn_wait->show();
            this->ui->btn_wait->setText(tr("Back"));
            this->ui->btn_wait->setFocus();
            this->ui->sw->setCurrentIndex(1);
        }
        break;
    default:
        break;
    }
}

void DLoginStdMng::slotBTN(){
    // принимаем нажатия от кнопки в закладке информации
    switch(this->Step){
    case DLoginStdMng::ShowU:
        // текущий этап это отображение смены пароля в пользовательском режиме
        // необходимо вернуть юзверя в первую вкладку
        this->ui->sw->setCurrentIndex(0);
        break;
    case DLoginStdMng::ValidCurrPassErrU:
        // шаг показа ошибки в режиме пользователя
        // текущий пароль пользователя указан неверно
        // необходимо вернуть юзверя в 1 диалог
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowU;
        break;
    case DLoginStdMng::ChangePassErrU:
        // значит отображается ошибка
        // при нажатии на эскейпт надо вернуть в основную закладку
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowU;
        break;
    case DLoginStdMng::GetAllErrA:
        // значит отображается ошибка
        // получения списка юзеров, дальше продолжать нет смысла, делаем реджект
        this->reject();
        break;
    case DLoginStdMng::ValidCurrPassErrUA:
        // шаг показа ошибки в режиме админа
        // новые пароли несовпали.
        // необходимо вернуть админа в 1 диалог
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowUA;
        break;
    case DLoginStdMng::ChangePassErrUA:
        // значит отображается ошибка
        // при нажатии на эскейпт надо вернуть в основную закладку
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowUA;
        break;
    case DLoginStdMng::InfoUA:
        // отображается информация о смене пароля
        this->reject();
        break;
    default:
        break;
    }
}


void DLoginStdMng::reject(){
    // обрабатываем реджект, можно ли закрыть диалог.
    switch(this->Step){
        // пока режима защиты от реджекта нету, будет позже
        // например когда выполняется запрос, и то мы не блокируем а просто
        // спрашиваем будем ли отказываться от выполнения запроса.
    case DLoginStdMng::ValidPassErrU:
        // значит отображается ошибка
        // при нажатии на эскейпт надо вернуть в основную закладку
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowU;
        break;
    case DLoginStdMng::ValidCurrPassErrU:
        // шаг показа ошибки в режиме пользователя
        // текущий пароль пользователя указан неверно
        // необходимо вернуть юзверя в 1 диалог
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowU;
        break;
    case DLoginStdMng::ChangePassErrU:
        // значит отображается ошибка
        // при нажатии на эскейпт надо вернуть в основную закладку
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowU;
        break;
    case DLoginStdMng::QueryChangePassU:
        // по идее тут надо сказать юзеру что надо дождаться реакции на запрос в бд. fixit
        break;
    case DLoginStdMng::GetAllA:
        // по идее тут надо сказать юзеру что надо дождаться реакции на запрос в бд. fixit
        break;
    case DLoginStdMng::GetAllErrA:
        // значит отображается ошибка
        // получения списка юзеров, дальше продолжать нет смысла, делаем реджект
        this->accept();
        break;
    case DLoginStdMng::QueryChangePassUA:
        // по идее тут надо сказать юзеру что надо дождаться реакции на запрос в бд. fixit
        break;
    case DLoginStdMng::ShowUA:
        // отображается закладка редактирования юзера в режиме админа, при реджекте надо вернуть на
        // закладку со списком юзверей
        // и ставим шаг отображения списка
        this->Step=DLoginStdMng::ShowAll;
        this->ui->sw->setCurrentIndex(2);
        break;
    case DLoginStdMng::ValidCurrPassErrUA:
        // шаг показа ошибки в режиме админа
        // новые пароли несовпали.
        // необходимо вернуть админа в 1 диалог
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowUA;
        break;
    case DLoginStdMng::ChangePassErrUA:
        // значит отображается ошибка
        // при нажатии на эскейпт надо вернуть в основную закладку
        this->ui->sw->setCurrentIndex(0);
        // и устанавливаем шаг отображения
        this->Step=DLoginStdMng::ShowUA;
        break;
    case DLoginStdMng::InfoUA:
        // отображается информация о смене пароля
        // возвращаем админа к списку юзверей
        this->Step=DLoginStdMng::ShowAll;
        this->ui->sw->setCurrentIndex(2);
        break;
    default:
        this->accept();
        break;
    }


}

// метод который говорит диалогу о том что не прошла валидация текущего пароля
// пользователя в режиме пользователя
void DLoginStdMng::setValidationErrorU(){
    //
    this->Step=DLoginStdMng::ValidCurrPassErrU;
    this->ui->btn_wait->setText(tr("Back"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(tr("Error: current password do not match."));
}

// и ошибка этого запроса
void DLoginStdMng::setValidationErrorUE(const QString & errortext){
    //
    this->Step=DLoginStdMng::ValidCurrPassErrU;
    this->ui->btn_wait->setText(tr("Back"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(QString(tr("Database error: \n<%1>")).arg(errortext));
}
// отдаем новый пароль
QString DLoginStdMng::getNewPass(){
    return this->ui->le_newpass1->text();
}

// пароль сменился удачно
void DLoginStdMng::setChangePassOkU(){
    // текущий шаг это отображение 1 закладки
    this->Step=DLoginStdMng::ShowU;
    this->ui->btn_wait->setText(tr("Back"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(tr("Info: change password is success."));
    // заранее подчищаем в 1 закладке все текстовые поля.
    // вдруг еще раз захочет чего сменить
    this->ui->le_curpass->clear();
    this->ui->le_newpass1->clear();
    this->ui->le_newpass2->clear();
    this->ui->sw->setCurrentIndex(1);

}
// пароль неудалось сменить
void DLoginStdMng::setChangePassErrU(const QString & errortext){
    this->Step=DLoginStdMng::ChangePassErrU;
    this->ui->btn_wait->setText(tr("Back"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(QString(tr("Database error: \n<%1>")).arg(errortext));
}

// административный режим
// получаем список юзверей.
void DLoginStdMng::setGetAllUsersOkA(const QStringList & users){
    // а вот и наш список, отрисовываем списог
    this->ui->lw_users->clear();
    for(int i = 0; i < users.size(); i ++){
        this->ui->lw_users->insertItem(i,users.at(i));
    }
    this->Step=DLoginStdMng::ShowAll;
    this->ui->lw_users->setFocus();
    this->ui->sw->setCurrentIndex(2);
}
// а вот и ошибка получения списка юзверей
void DLoginStdMng::setGetAllUsersErrA(const QString & errtext){
    // словили обшибку при работе с базой, докладываем юзеру.
    this->Step=DLoginStdMng::GetAllErrA;
    this->ui->btn_wait->setText(tr("Close"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(QString(tr("Database error: \n<%1>")).arg(errtext));

}

// обрабатываем события из списка пользователей

void DLoginStdMng::slotAll(QModelIndex){
    this->userEdit();
}

bool DLoginStdMng::eventFilter(QObject *obj, QEvent *event){
    if (event->type() == QEvent::KeyPress) {
             QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
             if( keyEvent->key() == Qt::Key_Return){
                 this->userEdit();
             }
             return false;
         } else {
             // standard event processing
             return QObject::eventFilter(obj, event);
         }
}

void DLoginStdMng::userEdit(){
    // словили пользователя, теперь надо отобразить его в режиме редактирования.
    this->Step=DLoginStdMng::ShowUA;
    this->ui->lbl_currpas->hide();
    this->ui->le_curpass->hide();
    // зачищаем поля редактирования новых паролей
    this->ui->le_newpass1->clear();
    this->ui->le_newpass2->clear();
    this->ui->le_newpass1->setFocus();
    this->ui->lbl_user->setText(QString(tr("Current user %1")).arg(this->ui->lw_users->currentItem()->text()));
    this->ui->sw->setCurrentIndex(0);

}

// пароль сменился удачно
void DLoginStdMng::setChangePassOkUA(){
    // отрисовываем админу положительный ответ в закладке заглушке
    // и возвращаем его в список пользователей
    this->Step=DLoginStdMng::InfoUA;
    this->ui->btn_wait->setText(tr("Back to users list"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(tr("Info: change password is success."));
    // заранее подчищаем в 1 закладке все текстовые поля.
    // вдруг еще раз захочет чего сменить
    this->ui->sw->setCurrentIndex(1);

}



// пароль неудалось сменить
void DLoginStdMng::setChangePassErrUA(const QString & errortext){
    this->Step=DLoginStdMng::ChangePassErrUA;
    this->ui->btn_wait->setText(tr("Back"));
    this->ui->btn_wait->show();
    this->ui->btn_wait->setFocus();
    this->ui->lbl_wait->setText(QString(tr("Database error: \n<%1>")).arg(errortext));
}


DLoginStdMng::~DLoginStdMng()
{
    delete ui;
}
